package cn.net.xyan.easy.spring.jdbc.config;

import cn.net.xyan.easy.spring.core.config.AutoConfigManagerFactory;
import cn.net.xyan.easy.spring.core.config.IAutoConfigManager;
import cn.net.xyan.easy.spring.jdbc.utils.DataBaseServer;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.util.Properties;

/**
 * Created by xiashenpin on 15/11/8.
 */
@Configuration
public class JDBCConfiguration implements BeanDefinitionRegistryPostProcessor {


    private static String DBConfig = "db.properties";


    Logger logger = LoggerFactory.getLogger(JDBCConfiguration.class);

    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(){
        DBConfig = AutoConfigManagerFactory.autoConfigManager().readValue(IAutoConfigManager.DBConfigFileKey,String.class);
        PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
        configurer.setIgnoreUnresolvablePlaceholders(true);
        configurer.setLocation(new ClassPathResource(DBConfig));
        return configurer;
    }

    @Bean(destroyMethod = "close")
    public DataSource dataSource(ApplicationContext context,
                                 @Value("${hsqldb.enable}") String hsqldbEnable,
                                 @Value("${jdbc.driverClassName}") String jdbcDriverClassName,
                                 @Value("${jdbc.url}") String jdbcUrl,
                                 @Value("${jdbc.username}") String username,
                                 @Value("${jdbc.password}") String password) throws PropertyVetoException {

        Boolean localHsqldbEnable = false;


        if (hsqldbEnable!=null && Boolean.parseBoolean(hsqldbEnable) == true){

            DataBaseServer server = context.getBean(DataBaseServer.class);

            logger.info(server.getConnectURL());

           // if (jdbcUrl==null||jdbcUrl.length()==0)
                jdbcUrl = server.getConnectURL();
            localHsqldbEnable = true;
        }

        ComboPooledDataSource dataSource = new ComboPooledDataSource();

        dataSource.setDriverClass(jdbcDriverClassName);
        dataSource.setJdbcUrl(jdbcUrl);

        if (!localHsqldbEnable) {
            if (username != null && username.length() > 0)
                dataSource.setUser(username);

            if (password != null && password.length() > 0)
                dataSource.setPassword(password);
        }
        dataSource.setAcquireIncrement(3);
        dataSource.setMinPoolSize(20);
        dataSource.setMaxPoolSize(50);
        dataSource.setMaxIdleTime(100);
        dataSource.setCheckoutTimeout(5000);

        return dataSource;
    }



    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {

        try {
            DBConfig = AutoConfigManagerFactory.autoConfigManager().readValue(IAutoConfigManager.DBConfigFileKey,String.class);

            Resource resource = new ClassPathResource(DBConfig);
            Properties properties = new Properties();
            properties.load(resource.getInputStream());

            String hsqldb_enable = properties.getProperty("hsqldb.enable", "false");
            if (Boolean.parseBoolean(hsqldb_enable)) {

                String beanName = DataBaseServer.class.getCanonicalName();
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DataBaseServer.class).setLazyInit(true);

                builder.addPropertyValue("dbPath", properties.getProperty("hsqldb.path", "."));

                builder.addPropertyValue("dbName", properties.getProperty("hsqldb.name", "testDB"));

                String hsqldb_silent = properties.getProperty("hsqldb.silent", "true");
                builder.addPropertyValue("silent", Boolean.parseBoolean(hsqldb_silent));

                String hsqldb_port = properties.getProperty("hsqldb.port","2000");
                builder.addPropertyValue("port", Integer.parseInt(hsqldb_port));

                // Now add the bean definition with given bean name
                beanDefinitionRegistry.registerBeanDefinition(beanName, builder.getBeanDefinition());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}
